#include "myTimer.h"

#include <stdint.h>
#include <stdbool.h>
#include <stdlib.h>
#include "TM4C123GH6PM.h"
#include "driverlib/sysctl.h"
#include "driverlib/timer.h"
#include "driverlib/interrupt.h"
#include "inc/hw_ints.h"

#include "FreeRTOS.h"
#include "queue.h"

#include "mySerial/mySerial.h"
#include "LED/led.h"

static time_t cpuRunTime = 0; // 存放CPU运行的时间


/**
 * @brief    初始化定时器0实现us级中断,作为系统计时
 * @param    reloadValue   ：重装载值
 *                       ps：计数频率默认是系统时钟频率，系统时钟频率默认是80Mhz,
 *                           所以重装载值的计算方法为
 *                           reloadValue = 80000000/(1/time) - 1)
 *                           (目标溢出时间为time，单位是秒)
 * @retval   void
 */

void Timer0A_Init(uint16_t reloadValue)
{
  // 使能定时器
  SysCtlPeripheralEnable(SYSCTL_PERIPH_TIMER0);

  // 配置定时器，将定时器拆分，并配置拆分后的定时器A为周期性计数
  TimerConfigure(TIMER0_BASE, TIMER_CFG_SPLIT_PAIR | TIMER_CFG_A_PERIODIC_UP | TIMER_CFG_B_CAP_TIME_UP);

  // 设置定时器A装载值
  TimerLoadSet(TIMER0_BASE, TIMER_A, reloadValue);

  // 设置中断优先级
  IntPrioritySet(INT_TIMER0A, 3);

  // 定时器中断允许，中断事件为计数器计数溢出
  TimerIntEnable(TIMER0_BASE, TIMER_TIMA_TIMEOUT);

  // NVIC中允许定时器模块中断
  IntEnable(INT_TIMER0A);

  // 使能系统总中断
  IntMasterEnable();

  // 使能定时器
  TimerEnable(TIMER0_BASE, TIMER_A);
}

/**
 * @brief    初始化定时器5A实现ms级中断, 作为系统计时
 *           注意：若需要这么做，则定时器5A不能再有其他用途
 * @param    reloadValue   ：重装载值
 *                       ps：计数频率默认是系统时钟频率，系统时钟频率默认是80Mhz,
 *                           所以重装载值的计算方法为
 *                           reloadValue = 80000000/(1/time) - 1)
 *                           (目标溢出时间为time，单位是秒)
 * @retval   void
 */
void Timer5_Init(uint32_t reloadValue)
{
  // 使能定时器
  SysCtlPeripheralEnable(SYSCTL_PERIPH_TIMER5);

  // 配置定时器，将定时器拆分，并配置拆分后的定时器为周期性计数
  TimerConfigure(TIMER5_BASE, TIMER_CFG_PERIODIC_UP);

  // 设置定时器装载值
  TimerLoadSet(TIMER5_BASE, TIMER_A, reloadValue);

  // 设置中断优先级
  IntPrioritySet(INT_TIMER5A, 4<<5);

  // 定时器中断允许，中断事件为计数器计数溢出
  TimerIntEnable(TIMER5_BASE, TIMER_TIMA_TIMEOUT);

  // NVIC中允许定时器模块中断
  IntEnable(INT_TIMER5A);

  // 使能系统总中断
  IntMasterEnable();

  // 使能定时器
  TimerEnable(TIMER5_BASE, TIMER_A);
}

/**
 * @brief Gets the CPU running time, in milliseconds
 *
 * @return time_t
 */
time_t getCPURunTime(void)
{
  return cpuRunTime;
}

/**
 * @brief ms级定时器，实现系统计时
 *
 */
void TIMER5A_Handler(void)
{
  TimerIntClear(TIMER5_BASE, TIMER_TIMA_TIMEOUT);
  cpuRunTime++;
  static uartBuf_t uart0Buf_temp;
  if(uart0Buf.period < UART0_WAIT_PERIOD)
     uart0Buf.period++;
  else if(uart0Buf.period == UART0_WAIT_PERIOD){
    uart0Buf_temp.len = uart0Buf.len;
    uart0Buf_temp.data = (uint8_t *)malloc(uart0Buf.len);
    memcpy(uart0Buf_temp.data, uart0Buf.data, uart0Buf.len);
    uart0Buf.len = 0;
    xQueueSendFromISR(uart0Queue, &uart0Buf_temp, 0);
    uart0Buf.period++;
  }

  static uartBuf_t uart2Buf_temp;
  if(uart2Buf.period < UART2_WAIT_PERIOD)
     uart2Buf.period++;
  else if(uart2Buf.period == UART2_WAIT_PERIOD){
    uart2Buf_temp.len = uart2Buf.len;
    uart2Buf_temp.data = (uint8_t *)malloc(uart2Buf.len);
    memcpy(uart2Buf_temp.data, uart2Buf.data, uart2Buf.len);
    uart2Buf.len = 0;
    xQueueSendFromISR(uart2Queue, &uart2Buf_temp, 0);
    uart2Buf.period++;
  }

}
